package in.iqing.view.activity;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import butterknife.Bind;
import in.iqing.Constants;
import in.iqing.app.R;
import in.iqing.base.BaseActivity;
import in.iqing.control.util.ToastUtil;

/**
 * Created by neavo on 2015/6/1.
 */

public class DownloadActivity extends BaseActivity implements Handler.Callback {

	@Bind(R.id.progress_text)
	public TextView progressText;

	@Bind(R.id.download_progress)
	public ProgressBar downloadProgress;

	private File temp;
	private File target;
	private boolean flag = true;

	private Handler handler;
	private final static int WHAT_DONE = 0x0001;
	private final static int WHAT_ERROR = 0x0002;
	private final static int WHAT_FINISH = 0x0003;
	private final static int WHAT_PROGRESS_UPDATE = 0x0004;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_donwload);
	}

	@Override
	protected void onInitialize(Bundle savedInstanceState) {
		super.onInitialize(savedInstanceState);

		this.handler = new Handler(this);
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);

		try {
			Uri uri = Uri.parse(getIntent().getStringExtra("url"));

			String bookid = uri.getPathSegments().get(0);
			String volumeid = uri.getPathSegments().get(1).replace(".data", "");

			if (!TextUtils.isDigitsOnly(bookid) || !TextUtils.isDigitsOnly(volumeid)) {
				throw new Exception("URI Decode Error");
			}

			target = new File(Constants.DATADIR + "/" + bookid + "/" + volumeid + ".data");
			temp = new File(Constants.DATADIR + "/" + bookid + "/" + volumeid + ".data.temp");

			if (!target.exists()) {
				downloadVolume(uri);
			} else {
				sendMessage(WHAT_FINISH, 0, 0, 0);
				ToastUtil.show(getContext(), R.string.activity_download_exist);
			}
		} catch (Exception e) {
			sendMessage(WHAT_ERROR, 0, 0, e);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();

		flag = false;
		sendMessage(WHAT_FINISH, 0, 0, 0);
	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
			case WHAT_FINISH:
				processFinish();
				break;
			case WHAT_DONE:
				processDone();
				break;
			case WHAT_ERROR:
				processWhatError((Exception) msg.obj);
				break;
			case WHAT_PROGRESS_UPDATE:
				processWhatProgressUpdate(msg.arg1, msg.arg2);
				break;
		}

		return false;
	}

	private void processDone() {
		sendMessage(WHAT_FINISH, 0, 0, 0);

		ToastUtil.show(getContext(), R.string.activity_download_success);
	}

	private void processFinish() {
		finish();
		FileUtils.deleteQuietly(temp);
	}

	private void processWhatError(Exception e) {
		e.printStackTrace();

		exit();
		ToastUtil.show(getContext(), e.getMessage());
	}

	private void processWhatProgressUpdate(int curr, int total) {
		downloadProgress.setMax(total);
		downloadProgress.setProgress(curr);

		progressText.setText(getString(R.string.activity_download_progress_update, curr / 1024, total / 1024));
	}

	private void downloadVolume(final Uri uri) throws IOException {
		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					File temp = new File(target + ".temp");
					HttpURLConnection connection = (HttpURLConnection) new URL(uri.toString()).openConnection();

					int curr = 0;
					int total = connection.getContentLength();

					InputStream is = connection.getInputStream();
					OutputStream os = FileUtils.openOutputStream(temp);

					int length;
					byte[] buffer = new byte[4096];
					while ((length = is.read(buffer)) != -1 && flag) {
						os.write(buffer, 0, length);
						curr = curr + length <= total ? curr + length : total;

						sendMessage(WHAT_PROGRESS_UPDATE, curr, total, 0);
					}

					IOUtils.closeQuietly(is);
					IOUtils.closeQuietly(os);

					if (flag) {
						FileUtils.moveFile(temp, target);
						sendMessage(WHAT_DONE, 0, 0, 0);
					}
				} catch (IOException e) {
					sendMessage(WHAT_ERROR, 0, 0, e);
				}
			}
		}).start();
	}

	private void sendMessage(int what, int arg1, int arg2, Object obj) {
		handler.sendMessage(handler.obtainMessage(what, arg1, arg2, obj));
	}
}
